/**
 * TopViewMotionController.java
 *
 * @author Somanath
 * @version 1.1 (last updated 16/6/07)
 *
 * class Dependencies: None
 */

 package gamepack;

 import java.util.Vector;

// For controling a sprite with horizontal and vertical motion.
// TODO:consider putting this class under a different package as it
// is a higher level function.
// Note: Make sure that you set the 'dir' attribute of you sprite
// in the constructor. If you don't you may see your sprite skid
// to the left direction, even though it visually appears to face
// a different direction. This is because by default the 'dir' is
// set to 0 which means left direction.
 public class TopViewMotionController implements MotionController {

        Sprite s;
        //private int curDir = Direction.NONE;
        private int maxSpeed;

        public TopViewMotionController( Sprite s , int maxSpeed) {
               this.s = s;
               this.maxSpeed = maxSpeed;
          }

         // Move sprite s based on input from joypad j
         // TODO: pass the previous direction while notifing direction change..
         // returns true if the sprite is moved or its direction is changed.
         // Sprite.canTurn(int newDirection)
        public boolean move(Joypad j ) {

/*void notify(int name,int value) {
 switch( name ) {
        case JoypadEvent.DIRECTION_CHANGE :  curFrame = value[0];
        //case JoypadEvent.MOVEMENT: curFrame ++; if ( curFrame > len ) curFrame =0;
 }
} */
              int dx=0,dy=0;
              boolean directionChanged = false;
                if(j.get(Joypad.Left) ) {
					if( s.dir != Direction.WEST ) {
					    if( s.canTurn( Direction.WEST ) ) {
					      int prevDirection = s.dir;
					      s.dir = Direction.WEST;
                          s.notify(JoypadEvent.DIRECTION_CHANGE, prevDirection);
                          directionChanged = true;
                        }
                    }
					else {
                         dx = -maxSpeed;	dy = 0;
                    }
				}
                else if(j.get(Joypad.Right) ) {
					  if( s.dir != Direction.EAST ) {
					    if( s.canTurn( Direction.EAST ) ) {
					      int prevDirection = s.dir;
	  				      s.dir = Direction.EAST;
                          s.notify(JoypadEvent.DIRECTION_CHANGE,prevDirection );
                          directionChanged = true;
                       }
                    }
					else {	dx = maxSpeed;	dy = 0; }
				}
                else if(j.get(Joypad.Up) ) {
					if( s.dir != Direction.NORTH ) {
					  if( s.canTurn( Direction.NORTH ) ) {
					    int prevDirection = s.dir;
					    s.dir = Direction.NORTH;
                        s.notify(JoypadEvent.DIRECTION_CHANGE,prevDirection );
                        directionChanged = true;
                      }
                    }
					else {	dx = 0;	dy = -maxSpeed; }
				}
                else if(j.get(Joypad.Down) ) {
					if( s.dir != Direction.SOUTH ) {
					  if( s.canTurn( Direction.SOUTH ) ) {
					    int prevDirection = s.dir;
					    s.dir = Direction.SOUTH;
                        s.notify(JoypadEvent.DIRECTION_CHANGE, prevDirection );
                        directionChanged = true;
                      }
                    }
					else {	dx = 0;   dy = maxSpeed; }
				}
			    else { dx = 0; dy = 0; }
			    MotionResult mr = Motion.canMove( s, dx, dy );
			    if ( mr.canMove ) {
       				Collidable c = Motion.move( s, mr.dx, mr.dy);
       				s.notify(JoypadEvent.MOVEMENT, dx, dy );
                    Vector<Collidable>[] vecCol = (Vector<Collidable>[]) s.colliders;
                    Vector<Collidable> vc = Collision.getCollisions( c, vecCol );
                    for( int i=0;i<vc.size();i++) {
                         Sprite prey = (Sprite) vc.get(i);
                         s.handleCollision( prey );
                    }
                } else {
                    if( directionChanged ) { return true; }
                    return false;
                }
                return true;
        }
 }